package com.lexue.articlesync.service;

import com.alibaba.fastjson.JSON;
import com.lexue.articlesync.entity.PlatformAuth;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 文件缓存服务 - 使用本地文件进行缓存存储
 */
@Slf4j
@Service
public class CacheService {
    
    @Value("${app.cache.dir:./cache}")
    private String cacheDir;
    
    private static final String AUTH_CACHE_PREFIX = "auth:";
    private static final String PLATFORM_CACHE_PREFIX = "platform:";
    private static final long DEFAULT_EXPIRE_HOURS = 24;
    
    /**
     * 缓存平台认证信息
     */
    public void cacheAuth(String platformCode, String userIdentifier, PlatformAuth auth) {
        String key = AUTH_CACHE_PREFIX + platformCode + ":" + userIdentifier;
        cacheToFile(key, auth);
        log.debug("缓存认证信息到文件: {}", key);
    }
    
    /**
     * 获取缓存的平台认证信息
     */
    public PlatformAuth getCachedAuth(String platformCode, String userIdentifier) {
        String key = AUTH_CACHE_PREFIX + platformCode + ":" + userIdentifier;
        PlatformAuth auth = getFromFile(key, PlatformAuth.class);
        
        if (auth != null) {
            log.debug("从文件缓存获取认证信息: {}", key);
        }
        
        return auth;
    }
    
    /**
     * 删除缓存的认证信息
     */
    public void removeCachedAuth(String platformCode, String userIdentifier) {
        String key = AUTH_CACHE_PREFIX + platformCode + ":" + userIdentifier;
        removeFileCache(key);
        log.debug("删除文件缓存认证信息: {}", key);
    }
    
    /**
     * 缓存平台配置信息
     */
    public void cachePlatformConfig(String platformCode, Object config) {
        String key = PLATFORM_CACHE_PREFIX + platformCode;
        cacheToFile(key, config);
        log.debug("缓存平台配置到文件: {}", key);
    }
    
    /**
     * 获取缓存的平台配置
     */
    public <T> T getCachedPlatformConfig(String platformCode, Class<T> clazz) {
        String key = PLATFORM_CACHE_PREFIX + platformCode;
        T config = getFromFile(key, clazz);
        
        if (config != null) {
            log.debug("从文件缓存获取平台配置: {}", key);
        }
        
        return config;
    }
    
    /**
     * 缓存到文件
     */
    private void cacheToFile(String key, Object value) {
        try {
            Path cacheFilePath = getCacheFilePath(key);
            
            // 创建缓存目录
            Files.createDirectories(cacheFilePath.getParent());
            
            // 构建缓存数据
            CacheData cacheData = new CacheData();
            cacheData.setKey(key);
            cacheData.setValue(JSON.toJSONString(value));
            cacheData.setCacheTime(LocalDateTime.now());
            cacheData.setExpireTime(LocalDateTime.now().plusHours(DEFAULT_EXPIRE_HOURS));
            
            // 写入文件
            try (FileWriter writer = new FileWriter(cacheFilePath.toFile())) {
                writer.write(JSON.toJSONString(cacheData));
            }
            
            log.debug("文件缓存写入成功: {}", cacheFilePath);
            
        } catch (Exception e) {
            log.error("文件缓存失败: {}", key, e);
        }
    }
    
    /**
     * 从文件获取缓存数据
     */
    private <T> T getFromFile(String key, Class<T> clazz) {
        try {
            Path cacheFilePath = getCacheFilePath(key);
            
            if (!Files.exists(cacheFilePath)) {
                log.debug("缓存文件不存在: {}", cacheFilePath);
                return null;
            }
            
            // 读取文件
            String content = Files.readString(cacheFilePath);
            CacheData cacheData = JSON.parseObject(content, CacheData.class);
            
            // 检查是否过期
            if (cacheData.getExpireTime().isBefore(LocalDateTime.now())) {
                // 过期了，删除文件
                Files.deleteIfExists(cacheFilePath);
                log.debug("缓存已过期，删除文件: {}", cacheFilePath);
                return null;
            }
            
            // 反序列化数据
            T result = JSON.parseObject(cacheData.getValue(), clazz);
            log.debug("从文件缓存读取成功: {}", cacheFilePath);
            return result;
            
        } catch (Exception e) {
            log.error("从文件获取缓存失败: {}", key, e);
        }
        return null;
    }
    
    /**
     * 删除文件缓存
     */
    private void removeFileCache(String key) {
        try {
            Path cacheFilePath = getCacheFilePath(key);
            if (Files.deleteIfExists(cacheFilePath)) {
                log.debug("删除缓存文件成功: {}", cacheFilePath);
            }
        } catch (Exception e) {
            log.error("删除文件缓存失败: {}", key, e);
        }
    }
    
    /**
     * 获取缓存文件路径
     */
    private Path getCacheFilePath(String key) {
        // 将key中的特殊字符替换为下划线，确保文件名合法
        String fileName = key.replaceAll("[^a-zA-Z0-9]", "_") + ".json";
        return Paths.get(cacheDir, fileName);
    }
    
    /**
     * 清理过期的文件缓存
     */
    public void cleanExpiredFileCache() {
        try {
            Path cacheDirPath = Paths.get(cacheDir);
            if (!Files.exists(cacheDirPath)) {
                log.debug("缓存目录不存在，无需清理: {}", cacheDirPath);
                return;
            }
            
            int cleanedCount = 0;
            List<Path> jsonFiles = Files.list(cacheDirPath)
                    .filter(p -> p.toString().endsWith(".json"))
                    .collect(Collectors.toList());
                    
            for (Path path : jsonFiles) {
                try {
                    String content = Files.readString(path);
                    CacheData cacheData = JSON.parseObject(content, CacheData.class);
                    
                    if (cacheData.getExpireTime().isBefore(LocalDateTime.now())) {
                        Files.deleteIfExists(path);
                        cleanedCount++;
                        log.debug("删除过期缓存文件: {}", path);
                    }
                } catch (Exception e) {
                    log.warn("清理缓存文件失败，删除损坏的文件: {}", path, e);
                    Files.deleteIfExists(path);
                    cleanedCount++;
                }
            }
            
            if (cleanedCount > 0) {
                log.info("清理过期缓存文件完成，删除了 {} 个文件", cleanedCount);
            }
                    
        } catch (Exception e) {
            log.error("清理过期文件缓存失败", e);
        }
    }
    
    /**
     * 清理指定平台的所有认证缓存
     */
    public int clearPlatformAuthCache(String platformCode) {
        try {
            Path cacheDirPath = Paths.get(cacheDir);
            if (!Files.exists(cacheDirPath)) {
                return 0;
            }
            
            String authPrefix = AUTH_CACHE_PREFIX + platformCode + ":";
            int clearedCount = 0;
            
            List<Path> jsonFiles = Files.list(cacheDirPath)
                    .filter(p -> p.toString().endsWith(".json"))
                    .collect(Collectors.toList());
                    
            for (Path path : jsonFiles) {
                try {
                    String content = Files.readString(path);
                    CacheData cacheData = JSON.parseObject(content, CacheData.class);
                    
                    // 检查是否是指定平台的认证缓存
                    if (cacheData.getKey().startsWith(authPrefix)) {
                        Files.deleteIfExists(path);
                        clearedCount++;
                        log.debug("删除平台 {} 的认证缓存文件: {}", platformCode, path);
                    }
                } catch (Exception e) {
                    log.warn("处理缓存文件失败: {}", path, e);
                }
            }
            
            log.info("清理平台 {} 的认证缓存完成，删除了 {} 个文件", platformCode, clearedCount);
            return clearedCount;
            
        } catch (Exception e) {
            log.error("清理平台认证缓存失败: {}", platformCode, e);
            return 0;
        }
    }
    
    /**
     * 清理所有缓存
     */
    public int clearAllCache() {
        try {
            Path cacheDirPath = Paths.get(cacheDir);
            if (!Files.exists(cacheDirPath)) {
                return 0;
            }
            
            int clearedCount = 0;
            List<Path> jsonFiles = Files.list(cacheDirPath)
                    .filter(p -> p.toString().endsWith(".json"))
                    .collect(Collectors.toList());
                    
            for (Path path : jsonFiles) {
                try {
                    Files.deleteIfExists(path);
                    clearedCount++;
                    log.debug("删除缓存文件: {}", path);
                } catch (Exception e) {
                    log.warn("删除缓存文件失败: {}", path, e);
                }
            }
            
            log.info("清理所有缓存完成，删除了 {} 个文件", clearedCount);
            return clearedCount;
            
        } catch (Exception e) {
            log.error("清理所有缓存失败", e);
            return 0;
        }
    }
    
    /**
     * 获取缓存统计信息
     */
    public CacheStats getCacheStats() {
        try {
            Path cacheDirPath = Paths.get(cacheDir);
            if (!Files.exists(cacheDirPath)) {
                return new CacheStats(0, 0, 0);
            }
            
            int totalFiles = 0;
            int validFiles = 0;
            int expiredFiles = 0;
            
            List<Path> jsonFiles = Files.list(cacheDirPath)
                    .filter(p -> p.toString().endsWith(".json"))
                    .collect(Collectors.toList());
                    
            for (Path path : jsonFiles) {
                totalFiles++;
                try {
                    String content = Files.readString(path);
                    CacheData cacheData = JSON.parseObject(content, CacheData.class);
                    
                    if (cacheData.getExpireTime().isBefore(LocalDateTime.now())) {
                        expiredFiles++;
                    } else {
                        validFiles++;
                    }
                } catch (Exception e) {
                    expiredFiles++; // 损坏的文件也算作过期
                }
            }
            
            return new CacheStats(totalFiles, validFiles, expiredFiles);
            
        } catch (Exception e) {
            log.error("获取缓存统计信息失败", e);
            return new CacheStats(0, 0, 0);
        }
    }
    
    /**
     * 缓存统计信息
     */
    public static class CacheStats {
        private final int totalFiles;
        private final int validFiles;
        private final int expiredFiles;
        
        public CacheStats(int totalFiles, int validFiles, int expiredFiles) {
            this.totalFiles = totalFiles;
            this.validFiles = validFiles;
            this.expiredFiles = expiredFiles;
        }
        
        public int getTotalFiles() { return totalFiles; }
        public int getValidFiles() { return validFiles; }
        public int getExpiredFiles() { return expiredFiles; }
        
        @Override
        public String toString() {
            return String.format("CacheStats{总文件数=%d, 有效文件数=%d, 过期文件数=%d}", 
                    totalFiles, validFiles, expiredFiles);
        }
    }
    
    /**
     * 缓存数据包装类
     */
    private static class CacheData {
        private String key;
        private String value;
        private LocalDateTime cacheTime;
        private LocalDateTime expireTime;
        
        // Getters and Setters
        public String getKey() { return key; }
        public void setKey(String key) { this.key = key; }
        
        public String getValue() { return value; }
        public void setValue(String value) { this.value = value; }
        
        public LocalDateTime getCacheTime() { return cacheTime; }
        public void setCacheTime(LocalDateTime cacheTime) { this.cacheTime = cacheTime; }
        
        public LocalDateTime getExpireTime() { return expireTime; }
        public void setExpireTime(LocalDateTime expireTime) { this.expireTime = expireTime; }
    }
}